﻿using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Net;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;

namespace G.APITest.Utils
{
    public static class MEFUtils
    {
        public static void LoadPart(Stream fileStream, object attributedPart)
        {
            AssemblyPart part = new AssemblyPart();
            Assembly ass = part.Load(fileStream); //提取程序集
            AssemblyCatalog cata = new AssemblyCatalog(ass);
            CompositionContainer container = new CompositionContainer(cata);
            CompositionBatch bat = new CompositionBatch();
            bat.AddPart(attributedPart);
            container.Compose(bat); //装配……
        }
        /// <summary>
        /// 加载模版
        /// </summary>
        /// <param name="path"></param>
        /// <param name="attributedPart"></param>
        public static void LoadPart(string path, object attributedPart)
        {
            using (var isofile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!string.IsNullOrWhiteSpace(path))
                {
                    if (isofile.FileExists(path))
                    {
                        var dllFile = isofile.OpenFile(path, FileMode.Open);
                        try
                        {
                            LoadPart(dllFile, attributedPart);
                        }
                        catch (Exception ex)
                        {
                            isofile.DeleteFile(path);
                        }
                        dllFile.Close();
                    }
                }
            }
        }

        /// <summary>
        /// 更新模版
        /// </summary>
        /// <param name="config"></param>
        public static void UpdatePart(APITest.Config.APIProjectConfig config)
        {
            var ProjectTemplateTable = ProjectTemplateTableUtils.LoadTable();
            var p = ProjectTemplateTable.FirstOrDefault(c => c.LocalPath == config.APIRequestPartPath);
            if (p == null)
            {
                MessageBox.Show("未找到相关模版！");
                return;
            }
            OpenFileDialog open = new OpenFileDialog();
            if (open.ShowDialog() == true)
            {
                try
                {
                    using (var fileStream = open.File.Open(System.IO.FileMode.Open, System.IO.FileAccess.Read))
                    {
                        var buffer = fileStream.GetBytes();
                        fileStream.Seek(0, SeekOrigin.Begin);
                        try
                        {
                            var orig = config.APIRequestPart;
                            config.APIRequestPart = null;
                            Utils.MEFUtils.LoadPart(fileStream, config);
                            if (config.APIRequestPart == null)
                            {
                                config.APIRequestPart = orig;
                                throw new Exception("");
                            }
                            //保存文件
                            using (var isofile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
                            {
                                if (isofile.FileExists(config.APIRequestPartPath))
                                    isofile.DeleteFile(config.APIRequestPartPath);
                                using (var dllFile = isofile.CreateFile(config.APIRequestPartPath))
                                {
                                    dllFile.Write(buffer, 0, buffer.Length);
                                    dllFile.Close();
                                }
                                Utils.ProjectTemplateTableUtils.SaveTable();
                            }
                            MessageBox.Show("部件更新完毕，重启程序以后生效");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("加载的DLL无效！无可装配的有效对象");
                        }
                        fileStream.Close();
                    }
                }
                catch (FieldAccessException ex)
                {
                    MessageBox.Show("只能读取文档下面的文件！");
                }
            }
        }

        /// <summary>
        /// 从独立存储删除模版
        /// </summary>
        /// <param name="p"></param>
        public static void DeletePartFromISO(G.APITest.Data.ProjectTemplate p)
        {
            if (MessageBox.Show("确定要删除？", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                var ProjectTemplateTable = ProjectTemplateTableUtils.LoadTable();
                if (p != null && ProjectTemplateTable.Contains(p))
                {
                    using (var isofile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        if (isofile.FileExists(p.LocalPath))
                            isofile.DeleteFile(p.LocalPath);
                    }
                    ProjectTemplateTable.Remove(p);
                    Utils.ProjectTemplateTableUtils.SaveTable();
                }
            }
        }

        public static void AddPartToIso(object attributedPart)
        {
            var import = attributedPart.GetType().GetProperties().FirstOrDefault(c =>
            {
                var att = Attribute.GetCustomAttribute(c, typeof(ImportAttribute)) as ImportAttribute;
                if ((att != null) && (att.ContractType == typeof(G.APITest.Part.IAPIRequestPart)))
                {
                    return true;
                }
                return false;
            });
            if (import == null)
            {
                MessageBox.Show("attributedPart没有标记为Import的属性");
                return;
            }
            var ProjectTemplateTable = ProjectTemplateTableUtils.LoadTable();
            OpenFileDialog open = new OpenFileDialog();
            if (open.ShowDialog() == true)
            {
                try
                {
                    using (var fileStream = open.File.Open(System.IO.FileMode.Open, System.IO.FileAccess.Read))
                    {
                        var buffer = fileStream.GetBytes();
                        fileStream.Seek(0, SeekOrigin.Begin);
                        var fileName = System.IO.Path.GetFileNameWithoutExtension(fileStream.Name);
                        if (ProjectTemplateTable.FirstOrDefault(c => c.Name == fileName) == null)
                        {
                            try
                            {
                                Utils.MEFUtils.LoadPart(fileStream, attributedPart);
                                if (import.GetValue(attributedPart, null) == null)
                                    throw new Exception("");
                                //保存文件
                                using (var isofile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
                                {
                                    using (var dllFile = isofile.CreateFile(LocalStaticConfig.ProjectTemplateDirectoryName + "/" + fileName))
                                    {
                                        dllFile.Write(buffer, 0, buffer.Length);
                                        dllFile.Close();
                                    }
                                    ProjectTemplateTable.Add(new Data.ProjectTemplate() { Name = fileName, LocalPath = LocalStaticConfig.ProjectTemplateDirectoryName + "/" + fileName });
                                    Utils.ProjectTemplateTableUtils.SaveTable();
                                }
                                MessageBox.Show("安装成功！请重启程序！");
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show("加载的DLL无效！无可装配的有效对象");
                            }
                        }
                        else
                        {
                            MessageBox.Show("已存在该模版");
                        }
                        fileStream.Close();
                    }
                }
                catch (FieldAccessException ex)
                {
                    MessageBox.Show("只能读取文档下面的文件！");
                }
            }
        }

        public static void AddPartToIso(object attributedPart, string url, string name)
        {
            var import = attributedPart.GetType().GetProperties().FirstOrDefault(c =>
            {
                var att = Attribute.GetCustomAttribute(c, typeof(ImportAttribute)) as ImportAttribute;
                if ((att != null) && (att.ContractType == typeof(G.APITest.Part.IAPIRequestPart)))
                {
                    return true;
                }
                return false;
            });
            if (import == null)
            {
                MessageBox.Show("attributedPart没有标记为Import的属性");
                return;
            }
            var ProjectTemplateTable = ProjectTemplateTableUtils.LoadTable();
            if (ProjectTemplateTable.FirstOrDefault(c => c.Name == name) != null)
            {
                MessageBox.Show("已存在该模版");
                return;
            }
            WebClient client = new WebClient();
            client.OpenReadCompleted += (s, e) =>
            {
                if (e.Error == null)
                {
                    try
                    {
                        var buffer = e.Result.GetBytes();
                        e.Result.Seek(0, SeekOrigin.Begin);
                        var orig = import.GetValue(attributedPart, null);
                        import.SetValue(attributedPart, null, null);
                        Utils.MEFUtils.LoadPart(e.Result, attributedPart);
                        if (import.GetValue(attributedPart, null) == null)
                        {
                            import.SetValue(attributedPart, orig, null);
                            throw new Exception("");
                        }
                        //保存文件
                        using (var isofile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
                        {
                            using (var dllFile = isofile.CreateFile(LocalStaticConfig.ProjectTemplateDirectoryName + "/" + name))
                            {
                                dllFile.Write(buffer, 0, buffer.Length);
                                dllFile.Close();
                            }
                            ProjectTemplateTable.Add(new Data.ProjectTemplate() { Name = name, LocalPath = LocalStaticConfig.ProjectTemplateDirectoryName + "/" + name, ProjectTemplateSource = Data.ProjectTemplateSource.Internet, Url = url });
                            Utils.ProjectTemplateTableUtils.SaveTable();
                        }
                        MessageBox.Show("安装成功！请重启程序！");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("加载的DLL无效！无可装配的有效对象");
                    }
                }
                else
                {
                    MessageBox.Show("下载失败！");
                }
            };
            client.OpenReadAsync(new Uri(url));
        }
    }
}
